#include "my_app_release.h"

#define APP_ANGLE_SW_PIN LL_GPIO_PIN_6
#define APP_ANGLE_SW_PORT GPIOB

//#define RELEASE_STUCK_AD_THRESHOLD (0x15A)
#define RELEASE_STUCK_AD_THRESHOLD (200)

static void app_motor_angle_sw_init(void);

static unsigned char get_angle_sw_ok(void);
static void set_angle_sw_ok(unsigned char value);
unsigned char angle_sw_ok = 0;

app_motor_mgr_t sg_motor_mgr = {0};

void my_app_release_init(void)
{
    drv_motor_init();
    app_motor_angle_sw_init();
    sg_motor_mgr.running = 0;
    sg_motor_mgr.counter = 0;
    dp_obj->state = FEED_STANDBY; // 喂食状态更新
    app_dp_feed_state_notify();
}

void my_app_release_task(void)
{
    app_overcur_handle();
    if (sg_motor_mgr.done_value < sg_motor_mgr.set_value && sg_motor_mgr.running == 0)
    {
        sg_motor_mgr.running = 1;
        app_motor_forward();
        dp_obj->state = FEED_FEEDING; // 喂食状态更新
        app_dp_feed_state_notify();
        sg_motor_mgr.start_time = app_sys_ticks;
        LL_EXTI_EnableIT(LL_EXTI_LINE_6);
    }
    if (sg_motor_mgr.running == 1)
    {
        if (time_after(app_sys_ticks, (sg_motor_mgr.start_time + 5000))) // 角度开关 超时
        {
            app_motor_reverse();
            sg_motor_mgr.running = 2;
            sg_motor_mgr.start_time = app_sys_ticks;
            LL_EXTI_DisableIT(LL_EXTI_LINE_6);
        }
    }
    if (sg_motor_mgr.running == 2) // 异常反转
    {
        if (time_after(app_sys_ticks, (sg_motor_mgr.start_time + 5000))) // 反转5s
        {
            sg_motor_mgr.running = 3;
            app_motor_forward();
            set_angle_sw_ok(ANGLE_SW_NONE);
            sg_motor_mgr.start_time = app_sys_ticks;
            LL_EXTI_EnableIT(LL_EXTI_LINE_6);
        }
    }
    if (sg_motor_mgr.running == 3) // 异常正转
    {
        if (time_after(app_sys_ticks, (sg_motor_mgr.start_time + 5000))) // 正转5s
        {
            sg_motor_mgr.reverse_count += 1;
            if (sg_motor_mgr.reverse_count >= 6)
            {
                sg_motor_mgr.reverse_count = 0;
                sg_motor_mgr.running = 0;
                if (sg_burn_mgr.state == 0)
                    app_motor_stop();
                app_set_alarm_jam(1);
                app_led_toggle(APP_LED_JAM, APP_TOGGLE_SLOW_TIME, 0x00);
                if ((dp_obj->fault & (1 << FOOD_JAM)) == 0) // 故障发生上报
                {
                    dp_obj->fault |= (1 << FOOD_JAM);
                    app_dp_fault_notify();
                }
                dp_obj->state = FEED_STANDBY; // 喂食状态更新
                app_dp_feed_state_notify();
                sg_motor_mgr.done_value = 0;
                sg_motor_mgr.set_value = 0;
                return;
            }
            sg_motor_mgr.running = 2;
            app_motor_reverse();
            sg_motor_mgr.start_time = app_sys_ticks;
        }
    }
}

static void app_motor_angle_sw_init(void)
{
    LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOB);
    LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
    LL_EXTI_InitTypeDef EXTI_InitStruct = {0};

    GPIO_InitStruct.Pin = APP_ANGLE_SW_PIN;
    GPIO_InitStruct.Mode = LL_GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
    LL_GPIO_Init(APP_ANGLE_SW_PORT, &GPIO_InitStruct);

    EXTI_InitStruct.Line = LL_EXTI_LINE_6;
    EXTI_InitStruct.LineCommand = ENABLE;
    EXTI_InitStruct.Mode = LL_EXTI_MODE_IT_EVENT;
    EXTI_InitStruct.Trigger = LL_EXTI_TRIGGER_RISING;
    LL_EXTI_Init(&EXTI_InitStruct);

    LL_EXTI_SetEXTISource(LL_EXTI_CONFIG_PORTB, LL_EXTI_CONFIG_LINE6);

    NVIC_SetPriority(EXTI4_15_IRQn, 0);
    NVIC_EnableIRQ(EXTI4_15_IRQn);
}

void irq_callback_angle_sw(void)
{
    sg_motor_mgr.done_value += 1;
    sg_motor_mgr.start_time = app_sys_ticks;
    if (sg_motor_mgr.running == 3)
        sg_motor_mgr.running = 1;                          // 异常正转时 正常返回正常正转
    if (sg_motor_mgr.done_value >= sg_motor_mgr.set_value) // 喂食份数全部完成
    {
        if (sg_burn_mgr.state == 0)
            app_motor_stop();
        dp_obj->result = sg_motor_mgr.done_value;
        if (dev_obj->tuya_net == TUYA_NET_OK)
            app_dp_feed_report_notify(); // 网络正常 喂食结果上报
        else
            app_time_rec_write(dp_obj->result); // 网络异常 存储数据
        app_set_alarm_jam(0);
        app_led_off(APP_LED_JAM);
        if (dp_obj->fault & (1 << FOOD_JAM)) // 故障清除上报
        {
            dp_obj->fault &= ~(1 << FOOD_JAM);
            app_dp_fault_notify();
        }
        dp_obj->state = FEED_STANDBY; // 喂食状态更新
        app_dp_feed_state_notify();
        sg_motor_mgr.done_value = 0;
        sg_motor_mgr.set_value = 0;
        sg_motor_mgr.running = 0;
    }
}
static unsigned char get_angle_sw_ok(void)
{
    return angle_sw_ok;
}
static void set_angle_sw_ok(unsigned char value)
{
    angle_sw_ok = value;
}

void app_release_set_value(unsigned char value)
{
    sg_motor_mgr.set_value = value;
}

unsigned char app_release_is_ok(void)
{
    if (sg_motor_mgr.running == 0x00 && app_motor_is_stopped())
    {
        return 0x01;
    }
    return 0x00;
}

void app_overcur_handle(void)
{
    sg_alarm_mgr.cur_ad = app_adc_convert(LL_ADC_CHANNEL_0);
    // printf("sg_alarm_mgr.cur_ad = %d\n", sg_alarm_mgr.cur_ad);
    // sg_alarm_mgr.cur = (unsigned int)(sg_alarm_mgr.cur_ad * 3300 / 4095.0); // 实时电压 单位mV 电阻1Ω 也是实时电流 单位mA
    if (sg_motor_mgr.running == 1)
    {
        if (sg_alarm_mgr.cur_ad > RELEASE_STUCK_AD_THRESHOLD)
        {
            app_motor_reverse();
            sg_motor_mgr.running = 2;
            sg_motor_mgr.start_time = app_sys_ticks;
            LL_EXTI_DisableIT(LL_EXTI_LINE_6);
        }
    }
    else if (sg_motor_mgr.running == 2)
    {
        if (sg_alarm_mgr.cur_ad > RELEASE_STUCK_AD_THRESHOLD)
        {
            sg_motor_mgr.running = 3;
            app_motor_forward();
            set_angle_sw_ok(ANGLE_SW_NONE);
            sg_motor_mgr.start_time = app_sys_ticks;
            LL_EXTI_EnableIT(LL_EXTI_LINE_6);
        }
    }
    else if (sg_motor_mgr.running == 3)   
    {
        if (sg_alarm_mgr.cur_ad > RELEASE_STUCK_AD_THRESHOLD)
        {
            sg_motor_mgr.reverse_count += 1;
            if (sg_motor_mgr.reverse_count >= 6)
            {
                sg_motor_mgr.reverse_count = 0;
                sg_motor_mgr.running = 0;
                if (sg_burn_mgr.state == 0)
                    app_motor_stop();
                app_set_alarm_jam(1);
                app_led_toggle(APP_LED_JAM, APP_TOGGLE_SLOW_TIME, 0x00);
                if ((dp_obj->fault & (1 << FOOD_JAM)) == 0) // 故障发生上报
                {
                    dp_obj->fault |= (1 << FOOD_JAM);
                    app_dp_fault_notify();
                }
                dp_obj->state = FEED_STANDBY; // 喂食状态更新
                app_dp_feed_state_notify();
                sg_motor_mgr.done_value = 0;
                sg_motor_mgr.set_value = 0;
                return;
            }
            sg_motor_mgr.running = 2;
            app_motor_reverse();
            sg_motor_mgr.start_time = app_sys_ticks;
        }        
    }
}
